package com.apes.crm.callCenter.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.crm.callCenter.model.CustomComplain;
import com.apes.crm.callCenter.repository.CallCenterDao;
import com.apes.crm.callCenter.repository.CustomComplainRepository;
import com.apes.crm.car.repository.CarBaseRepository;
import com.apes.crm.customerCar.model.CustomerCar;
import com.apes.crm.customerCar.repository.CustomerCarRepository;
import com.apes.crm.customerCar.service.CustomerCarService;
import com.apes.framework.api.DomainService;
import com.apes.framework.jpa.spec.PredicateBuilder;
import com.apes.framework.jpa.spec.Specifications;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.query.SqlService;
import com.apes.framework.util.MapUtil;
import com.apes.scm.masterdata.car.model.CarLabel;
import com.apes.scm.masterdata.contrast.repository.ContrastPartyCodeRepository;
import com.apes.scm.masterdata.enumeration.service.EnumerationService;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.frame.service.DeptService;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRepository;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.party.service.PartyRoleService;
import com.apes.scm.rbac.model.LocalPermitItem;
import com.apes.scm.rbac.model.Post;
import com.apes.scm.rbac.model.User;
import com.apes.scm.rbac.repository.LocalPermitItemRepository;
import com.apes.scm.rbac.repository.PostRepository;
import com.apes.scm.rbac.repository.UserRepository;
import com.apes.scm.rbac.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;

/**
 * 功能：CRM-客诉单
 *
 * @author Biebi
 * @create 2018-7-11 11:39:24
 */
@Service("crmCustomComplainService")
public class CustomComplainService extends DomainService {
    @Autowired
    CustomComplainRepository customComplainRepository;
    @Autowired
    EntityManager entityManager;
    @Autowired
    UserService userService;
    @Autowired
    UserRepository userRepository;
    @Autowired
    CommonForCallCenterService commonForCallCenterService;
    @Autowired
    ContrastPartyCodeRepository contrastPartyCodeRepository;
    @Autowired
    CustomerCarService customerCarService;
    @Autowired
    DeptService deptService;
    @Autowired
    CarBaseRepository CarBaseRepository;
    @Autowired
    EnumerationService enumerationService;
    @Autowired
    PartyRoleService partyRoleService;
    @Autowired
    SqlService sqlService;
    @Autowired
    PostRepository postRepository;
    @Autowired
    PartyRoleRepository partyRoleRepository;
    @Autowired
    PartyRepository partyRepository;
    @Autowired
    CallCenterDao callCenterDao;
    @Autowired
    CustomerCarRepository customerCarRepository;
    @Autowired
    LocalPermitItemRepository localPermitItemRepository;
    @Autowired
    DeptRepository deptRepository;

    /***
     * 功能：创建
     * @param request
     * @return
     */
    public CustomComplain create(SimpleRequest request) {
        try {
            CustomComplain customComplain = request.getO(CustomComplain.class);
            customComplain.setState("create");  //设置当前的状态
            return customComplainRepository.saveAndFlush(customComplain);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /***
     * 功能： 修改
     * @param request
     * @return
     */
    public CustomComplain update(SimpleRequest request) {
        String id = request.get("id");
        long versions = (int) request.get("version"); // 获取当前请求的版本信息
        CustomComplain customComplain = customComplainRepository.findOne(id);
        if (customComplain == null) throw new RuntimeException("客诉单【" + id + "】在系统中不存在。");
        if (customComplain.getVersion() != versions) throw new RuntimeException("记录已更新或已删除，请重新提交！");  // 用于判断当前版本是否被修改
        CustomComplain requestCustomComplain = request.getO(CustomComplain.class);
        requestCustomComplain = customComplainRepository.saveAndFlush(requestCustomComplain);
        return requestCustomComplain;
    }

    /***
     * 功能： 删除
     * @param request
     * @return
     * @throws RuntimeException
     */
    public String delete(SimpleRequest request) throws RuntimeException {
        String id = request.get("id");
        long versions = (int) request.get("version"); // 获取当前请求的版本信息
        CustomComplain customComplain = customComplainRepository.findOne(id);
        if (customComplain == null) throw new RuntimeException("离职申请单【" + id + "】在系统中不存在。");
        if (customComplain.getVersion() != versions) throw new RuntimeException("记录已更新或已删除，请重新提交！");  // 用于判断当前版本是否被修改

        // 设置删除人以及状态
        CustomComplain requestCustomComplain = request.getO(CustomComplain.class);

        requestCustomComplain.setDeleteId(this.getPerson(request)); //设置人员
        requestCustomComplain.setDeleteDate(new Date()); // 设置时间
        requestCustomComplain.setState("delete");  //设置当前的状态为删除
        customComplainRepository.saveAndFlush(requestCustomComplain);

        return "删除成功！";
    }


    /***
     * 功能 转OA start 节点
     * @param request
     * @return
     * @throws RuntimeException
     */
    public CustomComplain transOA(SimpleRequest request) throws RuntimeException {
        //设置单据状态为处理中
        CustomComplain customComplain = request.getO(CustomComplain.class);
        // 设置转OA人
        customComplain.setInitiatOaId(this.getPerson(request)); //设置人员
        customComplain.setInitiatOaDate(new Date()); // 设置时间
        customComplain.setState("disposing");  //设置当前的状态为处理中
        customComplain.setNextDisposeSign(String.valueOf(((User)getCurrentUser(request)).getId()));  //设置客诉节点的审批人
        customComplain = customComplainRepository.saveAndFlush(customComplain);
        return customComplain;
    }


    /***
     * 功能 部门处理节
     * @param request
     * @return
     * @throws RuntimeException
     */

    public CustomComplain transDispose(SimpleRequest request) {

        JSONObject tempJson = request.getJO();
        if (tempJson.get("nextDisposeSign") == null) throw new RuntimeException("节点候选人不能为空");
        //设置单据状态为处理中
        //获取最新的数据并设置状态
        CustomComplain customComplain = customComplainRepository.findOne((String) request.get("id"));
        customComplain.setState("disposing");  //设置当前的状态为处理中

        // 如果当前流程为挂起状态，执行挂起
        if (!customComplain.isActive()) {
            this.invoke("wf.suspend", MapUtil.mapper("innerBusinessType", customComplain.getInnerBusinessType(),
                    "innerBusinessKey", customComplain.getInnerBusinessKey()));
        }
        return customComplainRepository.saveAndFlush(customComplain);

    }

    public CustomComplain afterDispose(SimpleRequest request) {
        CustomComplain customComplain = customComplainRepository.findOne((String) request.get("id"));
        customComplain.setNextDisposeSign(String.valueOf(((User) this.getCurrentUser(request)).getId()));
        return customComplainRepository.saveAndFlush(customComplain); //设置客诉节点的审批人
    }


    /***
     * 功能 客户回访节点
     * @param request
     * @return
     * @throws RuntimeException
     */
    public CustomComplain transVisit(SimpleRequest request) {
        //设置单据状态
        CustomComplain customComplain = customComplainRepository.findOne((String) request.get("id"));

        //设置转客服回访日期和时间
        customComplain.setTransVisitId(this.getPerson(request));
        customComplain.setTransVisitDate(new Date());
        customComplain.setState("visiting");  //设置当前的状态为回访中
        return customComplainRepository.saveAndFlush(customComplain);
    }


    /***
     * 功能 end节点
     * @param request
     * @return
     * @throws RuntimeException
     */
    public CustomComplain transEnd(SimpleRequest request) throws RuntimeException {

        //设置单据状态
        CustomComplain customComplain = customComplainRepository.findOne((String) request.get("id"));
        customComplain.setState("end");  //设置当前的状态为结单

        //设置结单人，结单日期
        customComplain.setEndId(this.getPerson(request));
        customComplain.setEndDate(new Date());

        return customComplainRepository.saveAndFlush(customComplain);
    }


    /***
     * 功能 停单申请节点
     * @param request
     * @return
     * @throws RuntimeException
     */
    public CustomComplain transApplyStop(SimpleRequest request) throws RuntimeException {
        //设置单据状态
        CustomComplain customComplain = request.getO(CustomComplain.class);  //设置javaBean 并格式化时间

        if (customComplain.getStartDate() == null) {
            throw new RuntimeException("启单日期不能为空");
        } else {
            if (customComplain.getStartDate().before(new Date())) {
                throw new RuntimeException("启单日期不能小于当前时间");
            }
        }

        //设置转停单日期和时间
        customComplain.setTranstopId(this.getPerson(request));
        customComplain.setTranstopDate(new Date());
        customComplain.setState("transStop");  //设置当前的状态为停单申请中

        return customComplainRepository.saveAndFlush(customComplain);
    }


    /***
     * 功能： 挂起
     * @param request
     * @return
     */
    public CustomComplain suspend(SimpleRequest request) {
        CustomComplain customComplain = request.getO(CustomComplain.class);  //设置javaBean 并格式化时间
        customComplain.setStopId(this.getPerson(request));
        customComplain.setStopDate(new Date());
        customComplain.setActive(false); //设置激活状态为false
        return customComplainRepository.saveAndFlush(customComplain);
    }

    /***
     * 功能： 手动启单(激活)
     * @param request
     * @return
     */
    public CustomComplain active(SimpleRequest request) {
        //设置单据状态
        CustomComplain customComplain = request.getO(CustomComplain.class);  //设置javaBean 并格式化时间
        customComplain.setStartId(this.getPerson(request));
        customComplain.setRealStartDate(new Date());  //设置实际启单日期
        customComplain.setActive(true);

        this.invoke("wf.activate", MapUtil.mapper("innerBusinessType", customComplain.getInnerBusinessType(),
                "innerBusinessKey", customComplain.getInnerBusinessKey()));

        return customComplainRepository.saveAndFlush(customComplain);
    }


    /***
     * 功能 分配责任人
     * @param request
     * @return
     * @throws RuntimeException
     */
    public CustomComplain assign(SimpleRequest request) {
        JSONObject tempObj = request.getJO(); // 获取对象
        CustomComplain customComplain = request.getO(CustomComplain.class);  //设置javaBean 并格式化时间

        //设置分配人，分配日期
        customComplain.setAssignId(this.getPerson(request)); //设置人员
        customComplain.setAssignDate(new Date()); // 设置时间
        return customComplainRepository.saveAndFlush(customComplain);
    }


    /***
     * 查询客诉单报表
     * @param request(行政部门)
     * @return
     * @throws RuntimeException
     */
    public List queryReport(SimpleRequest request) throws RuntimeException {
        JSONObject tempJson = request.getJO(); // 获取对象
        if (tempJson.get("pdata") != null) tempJson.putAll(tempJson.getJSONObject("pdata"));
        if (tempJson.get("BRANCH_ID") == null) throw new RuntimeException("行政部门编码不能为空");
        List list = callCenterDao.queryReport(tempJson);

        // 插入操作员
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> map = (Map<String, Object>) list.get(i);
            List operateResult = callCenterDao.queryReport_findOperate(map);
            if (operateResult.size() > 0) {
                Map<String, Object> loggerObject = (Map<String, Object>) operateResult.get(0);
                map.put("OPERATE", loggerObject.get("OPERATE"));
            } else {
                map.put("OPERATE", "");
            }
        }
        return list;
    }


    /***
     * 功能： 查询会员信息(手机号, 投诉次数)
     * @param request
     * @return
     * @throws RuntimeException
     */
    public Map queryCustomerInfo(SimpleRequest request) {
        Map map = commonForCallCenterService.getCustomInfo(request);
        ;
        PartyRole customer = request.getO(PartyRole.class);
        map.put("complainCount", customComplainRepository.countCustomComplain(customer));
        return map;
    }


    /***
     * 功能：查询客诉单投诉走势报表
     * @param request
     * @return
     * @throws RuntimeException
     */
    public JSONArray queryComplainRateReport(SimpleRequest request) throws Exception {
        JSONObject tempObj = request.getJO(); // 获取对象
        JSONObject param = new JSONObject();

        if (request.get("START_DATE") == null || request.get("END_DATE") == null) {
            throw new RuntimeException("开始时间或者结束时间不能为空");
        }

        //判断时间的准确性
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Date START_DATE = sdf.parse(request.get("START_DATE"));
        Date END_DATE = sdf.parse(request.get("END_DATE"));
        param.put("START_DATE", sdf.format(START_DATE));
        param.put("END_DATE", sdf.format(END_DATE));

        // 获取远程数据的结果
        Map map = MapUtil.mapper("pdata", new Object(), "interfaceMethod", "ipmFwdForApesErpDao.queryComplainReport");
        JSONObject resultJson = JSONObject.parseObject(this.invoke("report.interface", map));
        JSONArray resultArray = JSONArray.parseArray(resultJson.getString("obj"));

        // 查询本地数据
        JSONArray array = callCenterDao.queryComplainRateReport(param);
        DecimalFormat decimalFormat = new DecimalFormat("##.00");
        JSONArray returnArr = new JSONArray();

        // 将本地数据与远程数据合并
        for (int i = 0, len = array.size(); i < len; i++) {
            JSONObject tempJson = array.getJSONObject(i);
            for (int j = 0, len1 = resultArray.size(); j < len1; j++) {
                JSONObject tempJson1 = resultArray.getJSONObject(j);
                if (tempJson.getString("MONTH").equals(tempJson1.getString("TJRQ"))) {
                    tempJson.put("XCMRTC", tempJson1.getIntValue("XCMRTC"));
                    tempJson.put("FXCMRTC", tempJson1.getIntValue("FXCMRTC"));
                    tempJson.put("CLJDTC", tempJson1.getIntValue("CLJDTC"));

                    if (tempJson1.getIntValue("XCMRTC") == 0) {
                        tempJson.put("XCMRTSL", "0.00");
                    } else {
                        double dd = tempJson.getDouble("XCMRTS") / tempJson1.getDouble("XCMRTC") * 100;
                        tempJson.put("XCMRTSL", Double.valueOf(decimalFormat.format(dd)));
                    }
                    if (tempJson1.getIntValue("FXCMRTC") == 0) {
                        tempJson.put("FXSMRTSL", "0.00");
                    } else {
                        double dd = tempJson.getDouble("FXCMRTS") / tempJson1.getDouble("FXCMRTC") * 100;
                        tempJson.put("FXSMRTSL", Double.valueOf(decimalFormat.format(dd)));
                    }
                    returnArr.add(tempJson);
                }
            }
        }
        return returnArr;
    }


    /***
     * 功能： 查询客诉单月报表
     * @param request
     * @return
     */
    public JSONArray queryComplainMonthReport(SimpleRequest request) throws Exception {
        JSONObject tempJson = new JSONObject();

        if (request.get("DATE") == null) throw new RuntimeException("日期条件不能为空");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Date date = sdf.parse(request.get("DATE"));
        tempJson.put("DATE", sdf.format(date));
        return callCenterDao.queryComplainMonthReport(tempJson);
    }

    /***
     * 功能: 查询所有流程
     * @param request
     * @return
     */
    public com.apestech.framework.json.JSONArray getAllProcess(SimpleRequest request) throws Exception {
        JSONObject param = request.getJO();
        try {
            if (param.getString("finished") != null && param.getString("finished") != "") {
                param.put("finished", param.getInteger("finished"));
            }
            boolean authed = param.containsKey("authed") ? param.getBoolean("authed") : true;
            if (authed) {
                List<LocalPermitItem> localPermitItems = localPermitItemRepository.find(request.getPostId(), "pp_search", "pt_dept");
                if (!localPermitItems.isEmpty()) {
                    //获取行政部门列表
                    List<String> ids = new ArrayList<>();
                    localPermitItems.forEach(e -> ids.add(e.getOrgId()));
                    List<String> branchIds = deptRepository.findDeptByIds(ids);
                    if (branchIds != null) param.put("branchIds", branchIds);
                }
            }
            // 处理待办岗位， 待办部门， 待办人
            param = dealUsers(param);

            // 查询主数据
            com.apestech.framework.json.JSONArray array =
                    sqlService.queryId("oa.queryAllProcess", new com.apestech.framework.json.JSONObject(param));
            com.apestech.framework.json.JSONObject tempJson;

            // 拼接数据
            for (int i = 0, len = array.size(); i < len; i++) {
                tempJson = array.getJSONObject(i);
                dealCandidate(new JSONObject(tempJson));
                dealTimeConsume(new JSONObject(tempJson));
                dealPreviousInfo(new JSONObject(tempJson));

                tempJson.put("businessKey", tempJson.get("BUSINESSKEY"));
                tempJson.put("processInitiator", tempJson.get("PROCESSINITIATOR"));
                tempJson.put("processInitiatingDepartment", tempJson.get("PROCESSINITIATINGDEPARTMENT"));
                tempJson.put("processInitiatingDate", tempJson.get("PROCESSINITIATINGDATE"));
                tempJson.put("name", tempJson.get("NAME"));
                tempJson.put("version", tempJson.get("VERSION"));

                tempJson.put("procInitId", tempJson.get("PROCINSTID"));
                tempJson.put("duration", tempJson.get("DURATION"));
                tempJson.put("curTaskName", tempJson.get("CURTASKNAME"));

                tempJson.remove("sqltype");
                tempJson.remove("nb_sql");
                tempJson.remove("autoCompletion");
                tempJson.remove("BUSINESSKEY");
                tempJson.remove("PROCESSINITIATOR");
                tempJson.remove("PROCESSINITIATINGDEPARTMENT");
                tempJson.remove("PROCESSINITIATINGDATE");
                tempJson.remove("NAME");
                tempJson.remove("VERSION");
                tempJson.remove("CURTASKNAME");
                tempJson.remove("PROCINSTID");
                tempJson.remove("DURATION");
            }
            return array;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /***
     * 功能： 查询 user
     * @param param
     * @return
     */
    private JSONObject dealUsers(JSONObject param) {
        try {
            // 判断岗位部门是否存在
            List users = new ArrayList();
            List<Post> posts = new ArrayList();
            if (param.get("processToDoUser") != null) {
                users.add(userRepository.findOne(param.getInteger("processToDoUser")).getId());
            } else if (param.get("processToDoDepartment") != null && param.get("processToDoWorkPost") != null) {
                List<Post> postList = postRepository.findAllByBranchIdAndWorkPostId(param.getString("processToDoDepartment"), param.getString("processToDoWorkPost"));
                posts.addAll(postList);
            } else if (param.get("processToDoDepartment") != null) {
                List<Post> postList = postRepository.findAllByBranchId(param.getString("processToDoDepartment"));
                posts.addAll(postList);
            } else if (param.get("processToDoWorkPost") != null) {
                List<Post> postList = postRepository.findAllByWorkPostId(param.getString("processToDoWorkPost"));
                posts.addAll(postList);
            }

            //posts 去重
            for (Post post : posts) {
                for (com.apes.scm.rbac.model.User user : post.getAssignedUsers()) {
                    if (user.isDisable()) continue; // 用于去除离职人员
                    if (users.contains(user.getId())) continue; // 用于去重
                    users.add(user.getId());
                }
            }
            if (users.size() > 0) {
                param.put("users", users);
            }
            return param;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    /***
     * 功能： 查询节点候选人以及签收人
     * @param tempJson
     */
    private void dealCandidate(JSONObject tempJson) {
        JSONArray tempArray;
        try {
            // 通过流程实例编码查询所有的候选人以及签收人
            if (tempJson.get("PROCINSTID") != null) {
                tempArray = callCenterDao.dealCandidate(tempJson);
                tempJson.put("candidate", tempArray.size() > 0 ? tempArray.getJSONObject(0).get("USERS") : "");
            } else {
                tempJson.put("candidate", "");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /***
     * 功能： 查询耗时
     * @param tempJson
     */

    private void dealTimeConsume(JSONObject tempJson) {
        JSONObject queryJson = new JSONObject();
        JSONArray suspendOrActiveArray;
        Date startDate;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            queryJson.put("taskId", tempJson.get("TASKID"));
            queryJson.put("processInstanceId", tempJson.get("PROCINSTID"));

            //查询节点耗时，流程耗时
            if (tempJson.get("DURATION") != null) {
                // 该流程已完结,无当前节点耗时
            } else {
                // 该流程未完结,有当前节点耗时
                Long endDate = new Date().getTime();
                startDate = tempJson.getDate("CREATEDATE");
                suspendOrActiveArray = callCenterDao.dealTimeConsume(queryJson);
                if (suspendOrActiveArray.size() > 0) {
                    JSONObject suspendOrActiveJson = suspendOrActiveArray.getJSONObject(0);
                    Date suspendOrActiveDate = suspendOrActiveJson.getDate("LONG_");
                    startDate = suspendOrActiveDate;
                }
                if (startDate == null) {
                    tempJson.put("nodeDuration", null);
                } else {
                    tempJson.put("createDate", format.format(startDate));
                    tempJson.put("nodeDuration", endDate - startDate.getTime());
                    tempJson.put("createDate", null);
                }
                tempJson.remove("CREATEDATE");
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    ;

    /***
     * 功能： 用于查询当前流程上一次的处理信息
     * @param temJson
     */
    private void dealPreviousInfo(JSONObject temJson) {
        JSONArray array = new JSONArray();
        try {
            if (temJson.get("BUSINESSKEY") == null) {
                temJson.put("previousInfo", "");
                return;
            }
            array = callCenterDao.dealPreviousInfo(temJson);
            if (array.size() > 0) {
                temJson.put("previousInfo", array.getJSONObject(0).get("INFO"));
            } else {
                temJson.put("previousInfo", "");
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

//    /***
//     * 功能： 处理前期数据
//     */
//    public void dealOrginData(SimpleRequest request) {
//        List<CustomComplain> list = customComplainRepository.findAllByOriginIsNullAndResponsiblePersonsIsNotNullOrComplainPersonsIsNotNull();
//        for( int i = 0, len = list.size(); i < len; i++ ){
//            CustomComplain customComplain = list.get(i);
//            if( customComplain.getResponsiblePersons() != null ){
//                customComplain.setResponsiblePersons(dealData(customComplain.getResponsiblePersons()));
//            }
//            if( customComplain.getComplainPersons() != null ){
//                customComplain.setComplainPersons(dealData(customComplain.getComplainPersons()));
//            }
//            customComplainRepository.saveAndFlush(customComplain);
//        }
//    }
//
//    private String dealData(String source){
//        Set<PartyRole> persons = new HashSet<>();
//        String[] rows = source.split(";");
//        for (String person : rows) {
//            if (person.contains("|")) {
//                persons.add(partyRoleRepository.findByPartyIdAndRoleId(Long.valueOf(StringUtils.split(person, "|")[0]), "Employee"));
//            }
//        }
//
//        StringBuffer sb = new StringBuffer();
//        for (PartyRole partyRole : persons) {
//            if (sb.length() > 0) {
//                sb.append(";");
//            }
//            sb.append(partyRole.getId());
//            sb.append("|");
//            sb.append(partyRole.getName());  // 格式 id|name;
//        }
//        return sb.toString();
//    }

    /***
     * 功能： 客诉总控节点接口
     * @param request
     * @return
     */
    public JSONArray complainControlsNode(SimpleRequest request) {
        JSONArray returnArray = new JSONArray();
        JSONObject param = request.getJO();
        if (param.get("pdata") != null) param.putAll(param.getJSONObject("pdata"));
        JSONArray customComplainArray = callCenterDao.queryForComplainControl(param);
        JSONObject customComplainJson = new JSONObject();
        for (int i = 0, len = customComplainArray.size(); i < len; i++) {
            JSONObject tempJson = new JSONObject();
            customComplainJson = customComplainArray.getJSONObject(i);
            jointBaseData(customComplainJson, tempJson);
            jointStepData(customComplainJson, tempJson);
            jointRecentRecordData(customComplainJson, tempJson);
            returnArray.add(tempJson);
        }
        return returnArray;
    }

    /***
     * 功能： 用于拼接基础数据
     * @param
     */
    private void jointBaseData(JSONObject customComplainJson, JSONObject returnJson) {
        JSONArray tempArr = new JSONArray();
        JSONObject tempJson = new JSONObject();
        tempJson.put("CPHM", customComplainJson.get("PLATE_NUMBER")); // 车牌号
        tempJson.put("MDMC", customComplainJson.get("DEPE_NAME"));  // 门店

        // 通过判断是否被挂起来计算耗时（ 当前时间 - 创建时间 - 挂起时间 ）
        long consumeTime = new Date().getTime() - customComplainJson.getDate("CREATE_DATE").getTime();
        if (customComplainJson.getDate("STOP_DATE") != null) {
            if (customComplainJson.getDate("REAL_START_DATE") != null && customComplainJson.getInteger("ACTIVE") != 0) {
                consumeTime = consumeTime - customComplainJson.getDate("REAL_START_DATE").getTime() + customComplainJson.getDate("STOP_DATE").getTime();
            } else {
                consumeTime = consumeTime - new Date().getTime() + customComplainJson.getDate("STOP_DATE").getTime();
            }
        }
        consumeTime = consumeTime / 1000 / 60;
        tempJson.put("consumeTime", consumeTime);

        // 获取商标
        if (customComplainJson.get("CAR_ID") != null) {
            CustomerCar customerCar = customerCarRepository.findOne(customComplainJson.getString("CAR_ID"));
            CarLabel carLabel = customerCar.queryCarLabel();
            if (carLabel != null) {
                String qccp = carLabel.getId();
                JSONArray qccbArray = callCenterDao.queryQQCB(qccp);
                if (qccbArray.size() > 0) {
                    tempJson.put("TPLJ", qccbArray.getJSONObject(0).getString("TPLJ"));
                }
            }
        }
        tempArr.add(tempJson);
        returnJson.put("jbArray", tempArr);
    }

    /***
     * 功能： 用于拼接步骤数据
     * @param
     */
    private void jointStepData(JSONObject customComplainJson, JSONObject returnJson) {
        JSONArray tempArr = new JSONArray();

        // 拼接第一步，客诉类型和客诉类别
        JSONObject step1 = new JSONObject();
        step1.put("status", "stringMore");
        step1.put("type", customComplainJson.getString("COMPLAIN_TYPE"));
        step1.put("Description", customComplainJson.getString("COMPLAIN_CATEGORY") == null ? "" : customComplainJson.getString("COMPLAIN_CATEGORY"));
        tempArr.add(step1);

        // 拼接第二步， 分两种情况（转OA以及未转OA）
        JSONObject step2 = new JSONObject();
        if (customComplainJson.get("INITIAT_OA_DATE") == null) {
            step2.put("status", "finish");
            step2.put("title", "待转OA");
            step2.put("icon", "anticon anticon-check");
            step2.put("Description", (new Date().getTime() - customComplainJson.getDate("CREATE_DATE").getTime()) / 1000 / 60);
        } else {
            step2.put("status", "finish");
            step2.put("title", "转OA");
            step2.put("icon", "anticon anticon-check");
            step2.put("Description", (customComplainJson.getDate("INITIAT_OA_DATE").getTime() - customComplainJson.getDate("CREATE_DATE").getTime()) / 1000 / 60);
        }
        if (step2.keySet().size() > 0) tempArr.add(step2);

        //拼接第三步 判断当前的状态去获取当前的OA状态
        JSONObject step3 = new JSONObject();
        if (customComplainJson.getString("STATE").equals("disposing")) {
            step3.put("status", "stringWait");
            step3.put("type", "客诉处理");
            step3 = getConsumeTimeAndAssigner(step3, customComplainJson);
        } else if (customComplainJson.getString("STATE").equals("visiting")) {
            step3.put("status", "stringWait");
            step3.put("type", "客服回访");
            step3 = getConsumeTimeAndAssigner(step3, customComplainJson);
        } else if (customComplainJson.getString("STATE").equals("transStop")) {
            step3.put("status", "stringWait");
            step3.put("type", "申请停单");
            step3 = getConsumeTimeAndAssigner(step3, customComplainJson);
        }

        if (tempArr.size() == 2) {
            tempArr.add(step3);
        }

        // 拼接第四步 结单
//        JSONObject step4 = new JSONObject();
//        step4.put("status", "wait");
//        step4.put("title", "结单");
//        step4.put("icon", "anticon anticon-question");
//        tempArr.add(step4);

        // 拼接第五步
        if (customComplainJson.getInteger("ACTIVE") == 0) {
            JSONObject step5 = new JSONObject();
            step5.put("status", "error");
            step5.put("title", "停单中");
            tempArr.add(step5);
        }

        returnJson.put("items", tempArr);

    }


    /***
     * 功能： 获取最近的处理记录以及投诉内容
     */
    private void jointRecentRecordData(JSONObject customComplainJson, JSONObject returnJson) {
        JSONObject param = new JSONObject();
        JSONArray tempArray = new JSONArray();
        JSONObject tempJson = new JSONObject();

        // 获取近期评论数据
        param.put("BUSINESSKEY", customComplainJson.get("ID"));
        param.put("BUSINESSTYPE", customComplainJson.get("INNER_BUSINESS_TYPE"));
        JSONArray array = callCenterDao.dealPreviousInfo(param);
        if (array.size() > 0) {
            tempJson.put("name", array.getJSONObject(0).get("NAME"));
            tempJson.put("time", array.getJSONObject(0).get("TIME"));
            tempJson.put("operate", array.getJSONObject(0).get("OPERATE"));
            tempJson.put("remark", array.getJSONObject(0).get("REMARK") == null ? "" : array.getJSONObject(0).get("REMARK"));
        } else {
            tempJson.put("name", "");
            tempJson.put("time", "");
            tempJson.put("remark", "");
            tempJson.put("operate", "");
        }

        // 投诉内容
        tempJson.put("lrr", customComplainJson.getString("CREATOR_NAME"));
        tempJson.put("lrrq_sj", customComplainJson.getString("CREATE_DATE"));
        tempJson.put("complainContent", customComplainJson.getString("COMPLAIN_CONTENT"));
        tempArray.add(tempJson);
        returnJson.put("tsArray", tempArray);
    }

    /***
     * 功能： 获取节点耗时以及候选人
     * @param
     */
    private JSONObject getConsumeTimeAndAssigner(JSONObject step3, JSONObject jsonObject) {
        JSONArray oaArr = callCenterDao.queryConsumeTime(jsonObject);
        if (oaArr.size() > 0) {
            // 节点耗时
            JSONObject oaJson = oaArr.getJSONObject(0);
            long createTime = oaJson.getDate("CREATEDATE").getTime();
            step3.put("Description", (new Date().getTime() - createTime) / 1000 / 60);
            // 候选人
            if (oaJson.get("PROCINSTID") != null) {
                JSONArray tempArray = callCenterDao.dealCandidate(oaJson);
                String user = tempArray.size() > 0 ? tempArray.getJSONObject(0).getString("USERS") : "";
                if (user == null) user = "";
                step3.put("title", user.indexOf(",") > -1 ? "" : user);
            }
        }
        return step3;
    }

    /***
     * 功能： 获取节点耗时以及候选人
     * @param
     */
    private JSONObject queryComplainNum(SimpleRequest request) {
        JSONObject param = request.getJO();
        if (param.get("pdata") != null) param.putAll(param.getJSONObject("pdata"));
        return callCenterDao.queryComplainNum(param).getJSONObject(0);
    }


    /***
     * 功能: 通过公司条件查询昨日客诉单数量以及月客诉总量(公司用逗号分隔)
     */
    public JSONObject getCustomComplainNum(SimpleRequest request) {
        JSONObject returnJson = new JSONObject();
        JSONObject param = request.getJO();
        if (param.get("pdata") != null) param.putAll(param.getJSONObject("pdata"));

        //昨日零点
        Date yestoday_start = Date.from(LocalDateTime.of(LocalDate.now().plusDays(-1), LocalTime.MIN)
                .atZone(ZoneId.systemDefault()).toInstant());

        Date today_start = Date.from(LocalDateTime.of(LocalDate.now(), LocalTime.MIN)
                .atZone(ZoneId.systemDefault()).toInstant());

        // 月头
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        Date month_start = calendar.getTime();

        returnJson.put("yesterdayNum", getNumBetweenDate(yestoday_start, today_start, param));
        returnJson.put("monthNum", getNumBetweenDate(month_start, new Date(), param));
        return returnJson;
    }


    private long getNumBetweenDate(Date startDate, Date endDate, JSONObject param) {
        PredicateBuilder pb = Specifications.and();
        if (param.get("companyId") != null)
            pb.in("company.id", param.getString("companyId").split(","));

        pb.gt("createDate", startDate);
        pb.le("createDate", endDate);
        pb.ne("responsibilityComplain.id", "000801");

        return customComplainRepository.count(pb.build(true));
    }
}
